/**
 *
 * Copyright (c) 2014 BinKylin Studio.
 *
 * Author: TBinkylin
 * Created Date: 2014-03-01
 * 
 * 	version					author					remark
 * 	1.0						benoit				
 */
package net.binkylin.common.utils;

import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CommonUtils {

	private static final Logger logger = LoggerFactory.getLogger(CommonUtils.class);

	public static synchronized String generateUniqueID() {
		final int NUM_CHARS = 5;
		final String chars = "abcdefghijklmonpqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		final Random r = new Random();
		char[] buf = new char[NUM_CHARS];
		for (int i = 0; i < buf.length; i++) {
			buf[i] = chars.charAt(r.nextInt(chars.length()));
		}
		return Long.toString((System.currentTimeMillis() / 1000L)) + new String(buf);
	}

	public static Timestamp getCurrentTimeStamp() {
		try {
			return new Timestamp(Calendar.getInstance().getTimeInMillis());
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
			return new Timestamp(Calendar.getInstance().getTimeInMillis());
		}
	}

	public static int getCurrentYear() {
		try {
			return Calendar.getInstance().get(Calendar.YEAR);
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
			return Calendar.getInstance().get(Calendar.YEAR);
		}
	}

	public static String replaceQuoteJSON(String searchString) {
		return (searchString == null || searchString.equalsIgnoreCase("")) ? "" : searchString.replace("\"", "\\\"").replaceAll(
				"\\r\\n|\\n|\\r", "<BR>");
	}

	public static Date getCurrentDate() {
		try {
			return Calendar.getInstance().getTime();
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
			return Calendar.getInstance().getTime();
		}
	}

	public static String[] splitValues(String splitValue, String splitSep) {
		String[] splitData = null;
		try {
			splitData = splitValue.split(splitSep);
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
		}
		return splitData;
	}

	public static Date stringToDate(String dateValue) {
		Date conDate = null;
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.sss");
		try {
			conDate = df.parse(dateValue);
		} catch (ParseException e) {
			logger.error("[MPA] error occurred: ", e);
		}
		return conDate;
	}

	public static String dateToString(Date dateValue) {
		String reportDate = null;
		DateFormat df1 = new SimpleDateFormat("dd-MMM-yyyy");
		try {
			reportDate = df1.format(dateValue);
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
		}
		return reportDate;
	}

	public static String dateToStringWithHHmm(Date dateValue) {
		String reportDate = null;
		DateFormat df1 = new SimpleDateFormat("dd/MM/yyyy HH:mm");
		try {
			reportDate = df1.format(dateValue);
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
		}
		return reportDate;
	}

	public static Timestamp addDaysToCurrentDate(int days) {
		Calendar c = Calendar.getInstance();
		try {
			c.add(Calendar.DAY_OF_MONTH, days);
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
		}
		return new Timestamp(c.getTimeInMillis());
	}

	public static String getCustomerGCIN(String d) {
		String ret;
		try {
			String[] a = d.split("-");
			ret = a[0];
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
			ret = d;
		}
		return ret;
	}

	public static String getCustomerNameHomePage(String d) {
		String ret;
		try {
			String[] a = d.split("-");
			ret = a.length > 1 ? d : a[0];
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
			ret = d;
		}
		return ret;
	}

	public static String getCustomerNameTree(String d) {
		String ret;
		try {
			String sep = "-";
			String[] a = d.split(sep);
			StringBuffer sb = new StringBuffer();
			for (int i = 1, j = a.length; i < j; i++) {
				sb.append(a[i] + sep);
			}
			if (sb.length() > 0) {
				sb.delete((sb.length() - sep.length()), sb.length());
			}
			ret = sb.toString();
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
			ret = d;
		}
		return ret;
	}

	/*
	 * Added the config property method to get the hostname and time from DMGR.
	 * This will be a solution for KAM clustering issue without triggering the
	 * KAM refresh twice.
	 */
	public static String getConfigProperty(String propertyName) {
		String propertyValue = null;
		try {
			Context context = new InitialContext();
			try {
				propertyValue = (String) context.lookup("cell/persistent/" + propertyName);
			} finally {
				try {
					context.close();
				} catch (Throwable ignore) {
					logger.error("[MPA] error occurred: ", ignore);
				}
			}
		} catch (NamingException ne) {
			logger.error("[MPA] error occurred: ", ne);
		}
		return propertyValue;
	}

	public static String getChartHTML(int w, int h, String swf, String xml) {
		String id = generateUniqueID(), chart = "c" + id, div = "d" + id, variable = "v" + id;
		StringBuffer s = new StringBuffer();
		s.append("<HTML><HEAD><TITLE></TITLE><META HTTP-EQUIV=\"PRAGMA\" CONTENT=\"NO-CACHE\"><META HTTP-EQUIV=\"CACHE-CONTROL\" CONTENT=\"NO-CACHE\"><META HTTP-EQUIV=\"EXPIRES\" CONTENT=\"0\"></HEAD><BODY>");
		s.append("<div id='" + div + "'></div>");
		s.append("<script type=\"text/javascript\">");
		s.append("var " + variable + " = new app.fusion.chart('include/swf/" + swf + "', '" + chart + "', '" + w + "', '" + h
				+ "', '0', '0');");
		s.append(variable + ".setDataXML(\"" + xml + "\");");
		s.append(variable + ".setTransparent(false);");
		s.append(variable + ".render('" + div + "');");
		s.append("</script></BODY></HTML>");
		return s.toString();
	}

	public static String makeXMLSafe(String s) {
		s = s.replace("&", "%26");
		s = s.replace("<", "%26lt;");
		s = s.replace(">", "%26gt;");
		s = s.replace("'", "%26apos;");
		s = s.replace("\"", "%26quot;");
		return s;
	}

	public static void sanitize(List objects) {
		try {
			if (objects != null && objects.size() > 0) {
				for (int i = 0; i < objects.size(); i++) {
					Object obj = objects.get(i);
					Class cl = obj.getClass();
					Method[] methods = cl.getDeclaredMethods();
					List<String> setMethods = new ArrayList<String>();
					for (Method method : methods) {
						if (method.getName().startsWith("set")) {
							if (method.getParameterTypes() != null && method.getParameterTypes().length == 1
									&& method.getParameterTypes()[0].getName().equals("java.lang.String")) {
								setMethods.add(method.getName());
							}
						}
					}
					for (String method : setMethods) {
						Method mthd = cl.getMethod(method.replace("set", "get"));
						String getvalue = (String) mthd.invoke(obj);
						if (getvalue != null && getvalue.trim().length() > 0) {
							Class[] par = new Class[1];
							par[0] = String.class;
							mthd = cl.getMethod(method, par);
							getvalue = getvalue.replace("&", "&amp;");
							getvalue = getvalue.replace("<", "&lt;");
							getvalue = getvalue.replace(">", "&gt;");
							// getvalue = getvalue.replace("'", "&apos;");
							getvalue = getvalue.replace("\"", "&quot;");
							mthd.invoke(obj, getvalue);
							mthd = cl.getMethod(method.replace("set", "get"));
							getvalue = (String) mthd.invoke(obj);
						}
					}
				}
			}
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
		}
	}

	public static String getLLRM(String lrm) {
		String ret = "";
		try {
			if (!lrm.trim().equals("")) {
				ret = lrm.substring(1, lrm.length() - 1).replaceAll(",", ", ");
			}
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
			ret = "";
		}
		return ret;
	}

	public static String getRowData(Object[] row, int index) {
		String ret;
		try {
			ret = row[index].toString();
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
			ret = "";
		}
		return ret;
	}

	public static Float getFloatData(String data) {
		Float fdata = null;
		try {
			fdata = Float.parseFloat(data);
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
		}
		return fdata;
	}

	public static String unique(String key) {
		String ret = "";
		try {
			if (!key.trim().equals("")) {
				String sep = ", ";
				Set<String> s = new HashSet<String>();

				String[] l = CommonUtils.splitValues(key, ",");
				StringBuffer sb = new StringBuffer();
				for (int i = 0; i < l.length; i++) {
					s.add(l[i]);
				}
				for (String n : s) {
					if (!n.trim().equals("")) {
						sb.append(n + sep);
					}
				}
				if (sb.length() > 0) {
					sb.delete((sb.length() - sep.length()), sb.length());
				}
				ret = sb.toString();
			}
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
			ret = "";
		}
		return ret;
	}

	public static String addPadding(String s) {
		// String ret = "";
		StringBuffer sb = new StringBuffer();
		sb.append("");
		int l = s.length();
		if (l < 900) {
			int tp = l / 100, j = 10 - tp;
			for (int i = 0; i < j; i++) {
				// ret = ret+"\n";
				sb.append("\n");
			}
		}
		// return ret;
		return sb.toString();
	}

	public static String getCustomerType(String s) {
		String ret = "Customer";
		if (s != null) {
			if (s.equalsIgnoreCase("GCINC PROSPECT") || s.equalsIgnoreCase("GCINI PROSPECT")) {
				ret = "Prospect";
			}
		}
		return ret;
	}

	public static Double getRowDataDid1000(Object[] row, int index) {
		Double ret = 0.0;
		try {
			if (row[index] == null)
				return 0.0;
			return getDividedBy1000(row[index].toString());
		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
		}
		return ret;
	}

	public static Double getDividedBy1000(String ret) {
		if (ret == null)
			return 0.0;
		try {
			double lv = Double.parseDouble(ret) / 1000;
			return ((double) Math.round(lv * 100)) / 100;

		} catch (Exception e) {
			logger.error("[MPA] error occurred: ", e);
			ret = "0";
		}
		return 0.0;
	}

	public static TimeUnit getJobTimeUnit(String timeUnit) {
		if ("1".equals(timeUnit)) {
			return TimeUnit.MICROSECONDS;
		} else if ("2".equals(timeUnit)) {
			return TimeUnit.MILLISECONDS;
		} else if ("3".equals(timeUnit)) {
			return TimeUnit.SECONDS;
		}
		return TimeUnit.HOURS;
	}

	public static String generateUniqueID(int index) {

		final int NUM_CHARS = 5;
		final String chars = "abcdefghijklmonpqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		final Random r = new Random();
		char[] buf = new char[NUM_CHARS];
		for (int i = 0; i < buf.length; i++) {
			buf[i] = chars.charAt(r.nextInt(chars.length()));
		}

		return Long.toString((System.currentTimeMillis() / 1000L)) + Integer.toString(index) + new String(buf);
	}

	// mengxuan change 2013-07-16 this method is special use for IE
	public static String generateUniqueIDStr(String systemName, int index) {

		final int NUM_CHARS = 5;
		final String chars = "abcdefghijklmonpqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		final Random r = new Random();
		char[] buf = new char[NUM_CHARS];
		for (int i = 0; i < buf.length; i++) {
			buf[i] = chars.charAt(r.nextInt(chars.length()));
		}

		String seq = String.valueOf(index);
		DecimalFormat df = new DecimalFormat("000000");
		seq = df.format(Integer.parseInt(seq));
		if (StringUtils.isBlank(systemName)) {
			systemName = "";
		}

		StringBuffer buffer = new StringBuffer();

		buffer.append(systemName.toUpperCase());
		buffer.append((System.currentTimeMillis() / 1000L));
		buffer.append(seq);
		buffer.append(new String(buf));

		return buffer.toString();
	}

}
